#ifndef BTREE_H
#define BTREE_H

#include "index_manager.h"
#include "../memory/memory_manager.h"
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>

// B+ tree node types
typedef enum {
    BTREE_NODE_LEAF = 0,
    BTREE_NODE_INTERNAL
} btree_node_type_t;

// Forward declarations
typedef struct btree_node btree_node_t;
typedef struct btree_entry btree_entry_t;
typedef struct btree_index btree_index_t;
typedef struct btree_iterator btree_iterator_t;

// B+ tree entry (key-value pair)
struct btree_entry {
    void* key;                 // Key data
    size_t key_size;          // Key size
    void* value;              // Value data (NULL for internal nodes)
    size_t value_size;        // Value size
    btree_node_t* child;      // Child pointer (for internal nodes)
};

// B+ tree node
struct btree_node {
    btree_node_type_t type;   // Node type (leaf or internal)
    bool is_root;             // Whether this is the root node
    uint32_t entry_count;     // Number of entries in this node
    uint32_t max_entries;     // Maximum entries this node can hold
    btree_entry_t* entries;   // Array of entries
    
    // Tree structure
    btree_node_t* parent;     // Parent node
    btree_node_t* next;       // Next sibling (for leaves)
    btree_node_t* prev;       // Previous sibling (for leaves)
    
    // Memory management
    memory_manager_t* memory_mgr;
    
    // Thread safety
    pthread_rwlock_t rwlock;
};

// B+ tree iterator state
struct btree_iterator {
    btree_index_t* index;     // Parent index
    btree_node_t* current_node; // Current leaf node
    uint32_t current_entry;   // Current entry index
    bool forward;             // Scan direction
    bool is_valid;            // Iterator validity
    
    // Range bounds (for range scans)
    void* start_key;
    size_t start_key_size;
    void* end_key;
    size_t end_key_size;
};

// B+ tree index structure
struct btree_index {
    btree_node_t* root;       // Root node
    uint32_t max_entries;     // Maximum entries per node
    uint32_t height;          // Tree height
    uint64_t total_entries;   // Total number of entries
    
    // Configuration
    uint32_t node_size;       // Node size in bytes
    bool allow_duplicates;    // Whether duplicates are allowed
    
    // Memory management
    memory_manager_t* memory_mgr;
    
    // Thread safety
    pthread_rwlock_t tree_lock;
    
    // Statistics
    uint64_t searches;
    uint64_t inserts;
    uint64_t deletes;
    uint64_t splits;
    uint64_t merges;
};

// B+ tree interface functions
index_interface_t* btree_interface_create(void);

// B+ tree implementation functions
btree_index_t* btree_create(memory_manager_t* memory_mgr, uint32_t node_size);
void btree_destroy(btree_index_t* btree);

// Core operations
index_result_t btree_insert(btree_index_t* btree, const void* key, size_t key_size,
                           const void* value, size_t value_size);
index_result_t btree_delete(btree_index_t* btree, const void* key, size_t key_size);
index_result_t btree_search(btree_index_t* btree, const void* key, size_t key_size,
                           index_search_result_t* result);
index_result_t btree_update(btree_index_t* btree, const void* key, size_t key_size,
                           const void* value, size_t value_size);

// Range operations
btree_iterator_t* btree_range_scan(btree_index_t* btree,
                                  const void* start_key, size_t start_key_size,
                                  const void* end_key, size_t end_key_size,
                                  bool forward);

// Iterator operations
bool btree_iterator_valid(btree_iterator_t* iter);
index_result_t btree_iterator_next(btree_iterator_t* iter);
index_result_t btree_iterator_current(btree_iterator_t* iter,
                                     void** key, size_t* key_size,
                                     void** value, size_t* value_size);
void btree_iterator_destroy(btree_iterator_t* iter);

// Bulk operations
index_result_t btree_bulk_insert(btree_index_t* btree,
                                const void** keys, size_t* key_sizes,
                                const void** values, size_t* value_sizes,
                                size_t count);
size_t btree_range_delete(btree_index_t* btree,
                         const void* start_key, size_t start_key_size,
                         const void* end_key, size_t end_key_size);

// Management operations
index_result_t btree_clear(btree_index_t* btree);
index_result_t btree_rebuild(btree_index_t* btree);
bool btree_validate(btree_index_t* btree);
void btree_get_stats(btree_index_t* btree, index_stats_t* stats);

// Node operations
btree_node_t* btree_node_create(memory_manager_t* memory_mgr, btree_node_type_t type, 
                               uint32_t max_entries);
void btree_node_destroy(btree_node_t* node);
index_result_t btree_node_insert_entry(btree_node_t* node, btree_entry_t* entry, uint32_t pos);
index_result_t btree_node_delete_entry(btree_node_t* node, uint32_t pos);
btree_node_t* btree_node_split(btree_node_t* node, btree_entry_t* new_entry);
index_result_t btree_node_merge(btree_node_t* left, btree_node_t* right);

// Key comparison
int btree_key_compare(const void* key1, size_t key1_size, const void* key2, size_t key2_size);
int btree_find_key_position(btree_node_t* node, const void* key, size_t key_size);

// Utility functions
void btree_print_tree(btree_index_t* btree);
void btree_print_node(btree_node_t* node, int level);

#endif // BTREE_H